﻿using System.Text;
using RAP.Framework.Libary.DomTemplateBuilder.Element.Conditional;
using RAP.Framework.Libary.DomTemplateBuilder.Element;
using RAP.Framework.Libary.DomTemplateBuilder.Interface;

namespace RAP.Framework.Libary.DomTemplateBuilder.Handler.Conditional
{
	/// <summary>
	/// 条件判断节点基类
	/// </summary>
	public abstract class ConditionalHandler : MutiplePropertyHandler
	{
		/// <summary>
		/// Handler对应的配置节点
		/// </summary>
		public virtual new ConditionalBase Element
		{
			get
			{
				return base.Element as ConditionalBase;
			}
			set
			{
				base.Element = value as ElementBase;
			}
		}

		/// <summary>
		/// 获取Else节点的Handler
		/// </summary>
		public ElseHandler ElseHandler
		{
			get
			{
				if ( this.Element.Else == null )
				{
					return null;
				}
				return this.Element.Else.Handler as ElseHandler;
			}
		}
		
		public override void DoRender ( StringBuilder writer, object rootParamObject, object parentParamObject, ITemplateRenderContext context )
		{
			if ( this.IsCondition ( rootParamObject, parentParamObject, context ) )
			{
				base.DoRender ( writer, rootParamObject, parentParamObject, context );
			}
			else
			{
				var elseHandler = this.ElseHandler;
				if ( elseHandler != null )
				{
					object paramObject = this.GetParamObject ( rootParamObject, parentParamObject, context );
					elseHandler.DoRender ( writer, rootParamObject, paramObject, context );
				}
			}
		}


		/// <summary>
		/// 判断是否满足条件
		/// </summary>
		/// <returns></returns>
		public virtual bool IsCondition ( object rootParamObject, object parentParamObject, ITemplateRenderContext context )
		{
			var propertyList = this.Property;
			var joinType = this.Element.JoinType;
			foreach ( var property in propertyList )
			{
				var propertyValue = this.GetExpressionValue
				(
					this.GetPropertyName ( property, rootParamObject, parentParamObject, context )
					, rootParamObject
					, parentParamObject
					, context
				);
				propertyValue = this.GetConvertedValue ( propertyValue );
				var compareResult = this.DoCompareValue ( propertyValue, rootParamObject, parentParamObject, context );
				switch ( joinType )
				{
					case ConditionJoinTypes.Or:
						if ( compareResult )
						{
							return true;
						}
						break;

					case ConditionJoinTypes.And:
						if ( !compareResult )
						{
							return false;
						}
						break;
				}
			}
			return joinType == ConditionJoinTypes.And;
		}

		/// <summary>
		/// 执行值的逻辑判断
		/// </summary>
		/// <param name="propertyValue"></param>
		/// <param name="rootParamObject"></param>
		/// <param name="parentParamObject"></param>
		/// <param name="context"></param>
		/// <returns></returns>
		protected virtual bool DoCompareValue ( object propertyValue, object rootParamObject, object parentParamObject, ITemplateRenderContext context )
		{
			return false;
		}
	}
}
